#include "PasteAction.hpp"

PasteAction::PasteAction(Map* map, vector<ClipboardPanel::CopyTile>* clipboard, int destX, int destY){
    desc = "Pasted clipboard to (" + StringHelper::itos(destX) +"," + StringHelper::itos(destY) + ")";
    target = map;
    destinationX = destX;
    destinationY = destY;

    clipboardWidth = 0;
    clipboardHeight = 0;
    for(int i = 0; i <clipboard->size(); i++){
        TileChanged tile;
        int tileX = destX + (clipboard->at(i).x);
        int tileY = destY + (clipboard->at(i).y);
        
        if(clipboardWidth < clipboard->at(i).x) clipboardWidth = clipboard->at(i).x;
        if(clipboardHeight < clipboard->at(i).y) clipboardHeight = clipboard->at(i).y;
        
        tile.layer = clipboard->at(i).layer;
        tile.val = clipboard->at(i).sprite;
        tile.tileX = tileX;
        tile.tileY = tileY;
        if(tileX >= 0 && tileX < target->width && tileY >= 0 && tileY < target->height)
            tile.original = target->tiles[tileY*target->width + tileX][tile.layer];
        else
            tile.original = NO_SPRITE;
        tiles.push_back(tile);
    }
    clipboardWidth++;
    clipboardHeight++;
    perform();
}

void PasteAction::perform(){
    resizeResult = 0;
    sf::Rect<int> clipboardArea;
    clipboardArea.left = destinationX;
    clipboardArea.top = destinationY;
    clipboardArea.width = clipboardWidth;
    clipboardArea.height = clipboardHeight;
    bool needsResize = MapResizer::needsResize(target, &clipboardArea);
    if(needsResize){
        resizeResult = MapResizer::resizeByMarquee(target, &clipboardArea);
        if(resizeResult != 0){
            for(int i = 0; i <tiles.size(); i++){
                target->tiles[(tiles.at(i).tileY + resizeResult->shiftY)*target->width
                        + tiles.at(i).tileX + resizeResult->shiftX][tiles.at(i).layer] = tiles.at(i).val;
            }
        }
    }
    if(resizeResult == 0){
        for(int i = 0; i <tiles.size(); i++){
            if(tiles.at(i).tileX < target->width && tiles.at(i).tileX >= 0 && tiles.at(i).tileY >= 0 && tiles.at(i).tileY < target->height)
                target->tiles[tiles.at(i).tileY*target->width + tiles.at(i).tileX][tiles.at(i).layer] = tiles.at(i).val;
        }
    }
}

void PasteAction::undo(){
    if(resizeResult != 0){
        for(int i = 0; i <tiles.size(); i++){
            target->tiles[(tiles.at(i).tileY + resizeResult->shiftY)*target->width
                    + tiles.at(i).tileX + resizeResult->shiftX][tiles.at(i).layer] = tiles.at(i).original;
        }
        MapResizer::shrink(target, resizeResult);
        delete resizeResult;
        resizeResult = 0;
    }else{
        for(int i = 0; i <tiles.size(); i++){
            if(tiles.at(i).tileX < target->width && tiles.at(i).tileX >= 0 && tiles.at(i).tileY >= 0 && tiles.at(i).tileY < target->height)
                target->tiles[tiles.at(i).tileY*target->width + tiles.at(i).tileX][tiles.at(i).layer] = tiles.at(i).original;
        }
    }
    
}

PasteAction::~PasteAction(){}